/*
 * MessageDispatcher.h
 * 
 * 消息分发器
 * 根据消息ID自动分发到对应的处理器
 * 支持 TcpConnection 和 Session 两种模式
 */

#pragma once

#include <muduo/base/Timestamp.h>
#include <muduo/base/Logging.h>
#include <muduo/net/TcpConnection.h>
#include <google/protobuf/message.h>
#include <functional>
#include <unordered_map>
#include <memory>
#include <string>

// 前向声明
namespace framework {
    class Session;
    typedef std::shared_ptr<Session> SessionPtr;
}

namespace protocol {

// 消息处理器类型定义（Session 版本）
// 参数：Session、Protobuf消息、时间戳
template<typename T>
using MessageHandler = std::function<void(
    const framework::SessionPtr&,
    const T&,
    muduo::Timestamp)>;

// 内部使用的通用处理器（Session 版本）
using GenericHandler = std::function<void(
    const framework::SessionPtr&,
    const std::string&,
    muduo::Timestamp)>;

// 兼容旧版本：TcpConnection 处理器
template<typename T>
using TcpMessageHandler = std::function<void(
    const muduo::net::TcpConnectionPtr&,
    const T&,
    muduo::Timestamp)>;

using TcpGenericHandler = std::function<void(
    const muduo::net::TcpConnectionPtr&,
    const std::string&,
    muduo::Timestamp)>;

class MessageDispatcher {
public:
    MessageDispatcher() = default;
    ~MessageDispatcher() = default;
    
    // 注册消息处理器（Session 版本）
    // 使用模板，自动处理 Protobuf 反序列化
    template<typename T>
    void registerHandler(uint16_t msgId, const MessageHandler<T>& handler) {
        // 包装成通用处理器
        handlers_[msgId] = [handler](const framework::SessionPtr& session,
                                    const std::string& data,
                                    muduo::Timestamp time) {
            // 反序列化 Protobuf 消息
            T message;
            if (!message.ParseFromString(data)) {
                LOG_ERROR << "Failed to parse protobuf message";
                return;
            }
            
            // 调用用户处理器
            handler(session, message, time);
        };
    }
    
    // 分发消息（Session 版本）
    // 根据 msgId 找到对应的处理器并调用
    void dispatch(const framework::SessionPtr& session,
                 uint16_t msgId,
                 const std::string& data,
                 muduo::Timestamp time) {
        auto it = handlers_.find(msgId);
        if (it != handlers_.end()) {
            // 调用处理器
            it->second(session, data, time);
        } else {
            LOG_WARN << "No handler for message ID: " << msgId;
        }
    }
    
    // 注册消息处理器（TcpConnection 版本，向后兼容）
    template<typename T>
    void registerTcpHandler(uint16_t msgId, const TcpMessageHandler<T>& handler) {
        tcpHandlers_[msgId] = [handler](const muduo::net::TcpConnectionPtr& conn,
                                       const std::string& data,
                                       muduo::Timestamp time) {
            T message;
            if (!message.ParseFromString(data)) {
                LOG_ERROR << "Failed to parse protobuf message";
                return;
            }
            handler(conn, message, time);
        };
    }
    
    // 分发消息（TcpConnection 版本，向后兼容）
    void dispatchTcp(const muduo::net::TcpConnectionPtr& conn,
                    uint16_t msgId,
                    const std::string& data,
                    muduo::Timestamp time) {
        auto it = tcpHandlers_.find(msgId);
        if (it != tcpHandlers_.end()) {
            it->second(conn, data, time);
        } else {
            LOG_WARN << "No TCP handler for message ID: " << msgId;
        }
    }
    
    // 检查是否注册了处理器
    bool hasHandler(uint16_t msgId) const {
        return handlers_.find(msgId) != handlers_.end();
    }

private:
    // 消息ID → 处理器映射（Session 版本）
    std::unordered_map<uint16_t, GenericHandler> handlers_;
    
    // 消息ID → 处理器映射（TcpConnection 版本，向后兼容）
    std::unordered_map<uint16_t, TcpGenericHandler> tcpHandlers_;
};

} // namespace protocol

